package com.example.cloud.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpRequest;
import org.springframework.http.MediaType;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.util.StreamUtils;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * RestTemplate配置类
 */
@Configuration
public class RestTemplateConfig {

    private static final Logger log = LoggerFactory.getLogger(RestTemplateConfig.class);

    /**
     * 创建RestTemplate Bean
     *
     * @return RestTemplate实例
     */
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate(clientHttpRequestFactory());
    }
    
    /**
     * 日志拦截器，记录请求和响应
     */
    static class LoggingInterceptor implements ClientHttpRequestInterceptor {
        @Override
        public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
            // 记录请求
            log.info("请求URL: {}", request.getURI());
            log.info("请求方法: {}", request.getMethod());
            log.info("请求头: {}", request.getHeaders());
            log.info("请求体: {}", new String(body, StandardCharsets.UTF_8));
            
            // 执行请求
            ClientHttpResponse response = execution.execute(request, body);
            
            // 记录响应
            log.info("响应状态码: {}", response.getStatusCode());
            log.info("响应头: {}", response.getHeaders());
            
            // 读取响应体
            byte[] responseBody = StreamUtils.copyToByteArray(response.getBody());
            log.info("响应体: {}", new String(responseBody, StandardCharsets.UTF_8));
            
            return response;
        }
    }
    
    /**
     * 配置消息转换器
     * @param restTemplate RestTemplate实例
     */
    private void configureMessageConverters(RestTemplate restTemplate) {
        // 获取现有的消息转换器
        List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters();
        
        // 添加StringHttpMessageConverter，支持text/plain
        StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
        stringConverter.setSupportedMediaTypes(Arrays.asList(
                MediaType.TEXT_PLAIN,
                MediaType.TEXT_HTML,
                MediaType.APPLICATION_JSON
        ));
        converters.add(0, stringConverter);
        
        // 添加MappingJackson2HttpMessageConverter，支持text/plain转换为JSON
        MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
        List<MediaType> mediaTypes = new ArrayList<>();
        mediaTypes.add(MediaType.APPLICATION_JSON);
        mediaTypes.add(MediaType.TEXT_PLAIN);  // 添加text/plain支持
        mediaTypes.add(MediaType.TEXT_HTML);   // 添加text/html支持
        jsonConverter.setSupportedMediaTypes(mediaTypes);
        converters.add(0, jsonConverter);
    }
    
    /**
     * 创建ClientHttpRequestFactory
     *
     * @return ClientHttpRequestFactory实例
     */
    private ClientHttpRequestFactory clientHttpRequestFactory() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        // 设置连接超时时间（毫秒）
        factory.setConnectTimeout(15000);
        // 设置读取超时时间（毫秒）
        factory.setReadTimeout(15000);
        return factory;
    }
}
